/*
* Copyright (c) 2008-2011, Thomas Handorf
* 
* This file is part of libScopes.
* libScopes is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* 
* libScopes is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* 
* You should have received a copy of the GNU Lesser General Public License
* along with libScopes.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifdef SCOPES_USEBOOSTSERIALIZATION
#include <boost/archive/text_oarchive.hpp> 
#include <boost/archive/text_iarchive.hpp> 
#endif // SCOPES_USEBOOSTSERIALIZATION
#include "array.h"
#include "net.h"
#include "scopes.h"
#include <iostream> 
#include <sstream> 
void test(const std::string& str1,const char* str2,const char* msg){
   printf("%s",msg);
   printf("...");
   if (str1.compare(str2)==0){
      printf("ok");
   } else {
      printf("fail: ");
      std::cout << str1;
   }
   printf("\n");
}


int main(){
   /*
   c0+c1->c2,c3+c2->c4+c5,c1->c6
   */ 
   Net* net=new Net;
   net->addRea(new VS(2,(size_t[]){0,1}),new VS(1,(size_t[]){2}));
   net->addRea(new VS(2,(size_t[]){3,2}),new VS(2,(size_t[]){4,5}));
   net->replaceRea(2,new VS(1,(size_t[]){1}),new VS(1,(size_t[]){6}));
   VC* sc=scope(net,new VC(7,(unsigned char[]){1,1,0,0,0,0,0}));
   sc->print();
   delete sc;
   sc=scope(net,new VC(7,(unsigned char[]){1,1,0,1,0,0,0}));
   sc->print();
   delete sc;
   net->print();
//   string *str=net->toString();
//   Net* net2=new Net(*str);
   Net* net2=new Net(*net);
   net2->print();
   sc=scope(net2,new VC(7,(unsigned char[]){1,1,0,1,0,0,0}));
   sc->print();
   delete sc;
   net2->replaceRea(1,new VS(2,(size_t[]){3,2}),new VS(2,(size_t[]){4,5}),0,NULL,NULL,new VS(1,(size_t[]){7}));
   net2->print();

   size_t idx=net->addRea(new VS(0),new VS(1,(size_t[]){2})); // producing reaction
   printf("added rea %ld\n",idx);
   net->print();

   /* network with inhibitions
   
   0 + 1 (c 10)=> 2 + 3
   4 isa 1 channel 0
   5 isa 1 channel 1
   6 isa 2 channel 0
   7 isa 2 channel 1
   7 (i 15)=> 8
   8|- => 9p
   9|- (c 11)=> 12
   8 => 13
   9 => 14
   
   
   */
   
   delete net;
   net=new Net;
   net->addRea(new VS(2,(size_t[]){0,1}),new VS(2,(size_t[]){2,3}),1,NULL,NULL,new VS(1,(size_t[]){10}));
   net->setMembers(1,new VS(2,(size_t[]){4,5}));
   net->setMembers(2,new VS(2,(size_t[]){6,7}));
   net->setChannels(4,new VS(1,(size_t[]){0}));
   net->setChannels(5,new VS(1,(size_t[]){1}));
   net->setChannels(6,new VS(1,(size_t[]){0}));
   net->setChannels(7,new VS(1,(size_t[]){1}));
   net->setChannels(1,new VS(2,(size_t[]){0,1}));
   net->setChannels(2,new VS(2,(size_t[]){0,1}));
   net->addRea(new VS(1,(size_t[]){7}),new VS(1,(size_t[]){8}),1,NULL,NULL,NULL,new VS(1,(size_t[]){15}));
   net->addRea(new VS(1,(size_t[]){8}),new VS(1,(size_t[]){13}));
   net->addRea(new VS(1,(size_t[]){9}),new VS(1,(size_t[]){14}));
   net->addRea(new VS(1,(size_t[]){8}),new VS(1,(size_t[]){9}),1,NULL,NULL,NULL,NULL,new VS(1,(size_t[]){8}),new VS(1,(size_t[]){9}));
   net->addRea(new VS(1,(size_t[]){9}),new VS(1,(size_t[]){12}),1,NULL,NULL,new VS(1,(size_t[]){11}),NULL,new VS(1,(size_t[]){9}),NULL);
   net->print_matrix();
   
   Channels* chn=new Channels(net);
   StateList* scopes;
   // note: lots of memory leaks ahead!!!!
   scopes=dScope(net,1000,new VC(16,(unsigned char[]){1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0}),NULL,chn);
   test(scopes->back()->present->printToString(),"[1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 0]","family seed");
   chn->clear();
   delete scopes;
   scopes=dScope(net,1000,new VC(16,(unsigned char[]){1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}),NULL,chn);
   test(scopes->back()->present->printToString(),"[1 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0]","no catalyst");
   chn->clear();
   delete scopes;
   scopes=dScope(net,1000,new VC(16,(unsigned char[]){1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0}),NULL,chn);
   /*   int i;
   for (i=0;i<scopes->size();i++){
      (*scopes)[i]->present->print();
}*/
   test(scopes->back()->present->printToString(),"[1 1 1 1 1 0 1 0 0 0 1 0 0 0 0 0]","family member seed");
   chn->clear();
   delete scopes;
   scopes=dScope(net,1000,new VC(16,(unsigned char[]){1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,1}),NULL,chn);
   test(scopes->back()->present->printToString(),"[1 1 1 1 1 1 1 1 0 0 1 0 0 0 0 1]","inhibition");
   chn->clear();
   delete scopes;
   scopes=dScope(net,1000,new VC(16,(unsigned char[]){1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0}),NULL,chn);
   size_t i;
   for (i=0;i<scopes->size();i++){
      (*scopes)[i]->combine()->print();
   }
   test(scopes->back()->combine()->printToString(),"[1 1 1 1 1 1 1 1 0 0 1 1 1 0 0 0]","substrate inhibition & propagation");
   chn->clear();
   delete scopes;
   
   // static scopes
   
   delete net;
   /*
   c0+c1->c2,c3+c2->c4+c5,c1->c6
   */ 
   net=new Net;
   net->addRea(new VS(2,(size_t[]){0,1}),new VS(1,(size_t[]){2}));
   net->addRea(new VS(2,(size_t[]){3,2}),new VS(2,(size_t[]){4,5}));
   net->replaceRea(2,new VS(1,(size_t[]){1}),new VS(1,(size_t[]){6}));
   
   sc=scope(net,new VC(7,(unsigned char[]){1,1,0,0,0,0,0}));
   test(sc->printToString(),"[1 1 1 0 0 0 1]","sScope: seed c0,c1");
   delete sc;

   sc=scope(net,new VC(7,(unsigned char[]){1,1,0,1,0,0,0}));
   test(sc->printToString(),"[1 1 1 1 1 1 1]","sScope: seed c0,c1,c3");
   delete sc;
   return 0;
}
